home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,132
- TITLE SETDISK.COM VER.2.0 14-AUG-83 19:15
- comment *
-
- SETDISK.COM
-
-
- VERSION 2.0 14-AUG-83
-
- Written by Warren Craycroft
- 6236 Oakdale Ave.
- Oakland, CA 94605
-
-
- (C) 1983 by Warren Craycroft. Permission is granted to copy and
- distribute this program, including source code, provided that no
- charge shall be made except for a reasonable charge for the media
- and handling, and that this notice shall remain intact in all copies.
-
-
- *
- comment *
- This program is a utility that can be used with DOS 2.0 to
- find the disk drive number that contains a certain file.
-
- SETDISK is similar to FINDFILE, with one additional feature.
- When SETDISK finds the file, it sets the DOS default
- drive designator to the drive on which the file was found.
-
- A common use of SETDISK is to help a batch file "orient"
- itself by discovering on which drive the Batch File itself is
- running, and on what drives other files (such as useful system
- utilities) can be found. A lot of this orientation can be done
- without bothering or confusing the user with a lot of questions
- or constraints in locating disks in certain drives.
-
- A key feature of this search (and where this method of orien-
- tation differs from the use of PATH or IF EXIST ) is that
- searching on the disk drives is done "benignly". By this we mean
- that SETDISK doesn't come to a grinding halt if an empty
- disk drive is searched. Instead, it continues the search on
- the rest of the drives. This further relieves the user from
- having to locate certain disks on certain drives. The target
- file may be on the B: or C: drive with the A: drive empty, and
- SETDISK will find it without the annoying "ignore, abort, retry"
- message. If the file is not found, then you may gently prod the
- user to place the required disk "in any drive" and try again.
-
- The syntax of the command line is the following:
-
- findfile fname
-
- where fname is a standard DOS path, filename, and extention.
- If you include a drive specification (like "a:" for example),
- the drive spec will be ignored by SETDISK.
-
- SETDISK benignly searches all disk drives that are claimed
- to be present by the system board switches, in order A:, B:, C:, and
- D:. If the file is found, the disk number of the first disk on
- which it was found is returned in errorlevel and may be tested
- by a Batch File IF Subcommand. SETDISK also changes the DOS default
- drive designator to the disk on which the file was found.
-
-
- If fname found: errorlev = 0 if fname on A:
- errorlev = 1 if fname on B:
- errorlev = 2 if fname on C:
- errorlev = 3 if fname on D:
- (in all of above cases, the default
- drive designator is changed to the
- drive on which fname was found )
-
- If fname not found: errorlev = 255
-
- If fname is missing: errorlev = 255 , and a CNTRL BREAK
- halts the Batch File
-
- *
- ;
- ; constant equates
- ;
- BEL_CHAR EQU 07 ;ascii BEL keycode
- CR EQU 0DH ;ascii carriage return
- LF EQU 0AH ;ascii line feed
- TAB_CHAR EQU 09 ;ascii tab
- BLANK_CHAR EQU ' ' ;ascii blank
- COLON_CHAR EQU ':' ;ascii colon
- NOT_FOUND_CODE EQU 255 ;errorlev returned for fname not
- ;found
- DISK_MASK EQU 00C0H ;mask for equipment word's disk
- ;count field
- ;
- ;
- ; declare a relocatable segment. Follow the .COM file requirements
- ; of entry point at 100H and making all seg register references relative
- ; to CS (no relocatable values MOV'ed into segment registers).
- ;
- ;
- COM_CODE SEGMENT
- ;
- ORG 80H ;PSP offset 80: user's command line
- PSP_CMD_LINE LABEL BYTE ;define a label for address refs
- ;
- ORG 100H ;for COM file
- ;
- ;
- ASSUME CS:COM_CODE,DS:COM_CODE ;tell assembler value of CS
- ASSUME ES:COM_CODE ; DS, and ES
- ;
- ;
- START PROC FAR ;FAR is meaningless; no RETS
- ;
- MOV SI,OFFSET PSP_CMD_LINE ;offset of user's cmd line
- SUB CX,CX ;clear CX
- MOV CL,[SI] ;byte count of line
- OR CL,CL ;zero?
- JZ NO_FNAME ;jump if yes, no fname param
- SUB BX,BX ;else zero index
- ;
- ; find first non-blank or non-tab character of command line
- ;
- STRIP_BLANKS: INC SI ;point to next char
- MOV AL,[SI] ;get next char from cmd line
- CMP AL,BLANK_CHAR ;is it blank?
- JE LOOP_BLANKS ;jump if yes, keep looking
- CMP AL,TAB_CHAR ;is it a tab?
- JNE GOT_NON_BLANK ;jump if not, first non-blank
- LOOP_BLANKS: LOOP STRIP_BLANKS ;else keep looking
- ;
- ; fname is missing from command line (all blanks or tabs, or else
- ; zero characters on line
- ;
- NO_FNAME: MOV DX,OFFSET ERROR_MESSAGE ;adr offset of error message
- MOV AH,9 ;DOS fn call, "print string"
- INT 21H ;call DOS
- INT 23H ;cause a control break, cause
- ;this is probably a bug in
- ;batch file creation.
- JMP NO_FILE_EXIT ;then exit with errorlevel =
- ; "NOT_FOUND_CODE"
- ;
- ; found first non-blank/tab character on command line
- ; at [SI][BX] . Check for disk designator " n: " and
- ; "strip" it from string by moving up pointer and decreasing
- ; remaining bytes count.
- ;
- GOT_NON_BLANK: CMP BYTE PTR [SI+1],COLON_CHAR ;2nd non-blank char ":"?
- JNE ADD_DRIVE ;if not, [SI] is start of strng
- INC SI ;else strip off the drive spec
- INC SI
- DEC CX ;and decr remaining byte count
- JZ NO_FNAME ;if string hits zero bytes left,
- DEC CX
- JZ NO_FNAME ; it's a "no param" error
- ;
- ; SI now points to start of ASCIIZ string that we want to use as
- ; the path/file name to search drives for
- ;
- ; Put a byte of zeros at the end of string, and an "A:" in front
- ; of string to initialize search.
- ;
- ADD_DRIVE: MOV BX,CX ;number of bytes remaining
- MOV BYTE PTR [SI][BX],0 ;points to 1 char past end
- ; of string
- MOV BYTE PTR [SI-2],'A' ;"A:" in front of string
- MOV BYTE PTR [SI-1],':'
- ;
- ; Replace the current critical error handler with our own
- ;
- ; First, get the address of the critical error handler assigned
- ; by "parent" process (probably system) to this process. Save its
- ; address, so that we can use it if our handler is handed a non-disk
- ; error ( "we don't do non-disk errors ..." )
- ;
- MOV AH,35H ;DOS fn "get vector"
- MOV AL,24H ;"critical error" vector no.
- INT 21H ;call DOS
- MOV WORD PTR PARENT_HAND,BX ;save offset vector adr
- MOV WORD PTR PARENT_HAND+2,ES ;save seg vector adr
- ;
- ; Now, take control of critical error vector by assigning a handler
- ; to the vector address.
- ;
- ; DOS will restore the "parent"'s vector when this process returns to
- ; DOS.
- ;
- MOV DX,OFFSET CRIT_HAND ;address of handler
- MOV AL,24H ;the vector to be replaced
- MOV AH,25H ;DOS fn call "ret int vector"
- INT 21H ;call DOS and replace vector
- ;
- ; Get the number of drives that DOS knows about
- ; Dont disturb the current default disk setting when getting number
- ; of drives from DOS.
- ;
- MOV AH,19H ;DOS fn "get current disk"
- INT 21H ;current disk retd in AL
- MOV DL,AL ;cur disk in DL for next call
- MOV AH,0EH ;DOS fn "sel disk, return numb"
- INT 21H ;number of drives retd in AL
- SUB CH,CH ;clear CH
- MOV CL,AL ;number of drives
- INC CX ;is now (1,2,3, or 4)
- ;
- ; Now loop through all drives present, trying to find the file
- ; (using fn call 4EH) on each drive. If successful, return the
- ; disk number to caller in errorlevel.
- ;
- ; If not successful, return errorlevel = NOT_FOUND_CODE
- ;
- MOV DX,SI ;offset adr of drive spec and
- DEC DX ; filename
- DEC DX
- FIND_FILE: MOV AH,4EH ;DOS fn "find first file"
- PUSH CX ;save the loop count
- SUB CX,CX ;attribute says search
- ;"normal" files only
- PUSH [SI-2] ;save drive letter (DOS call
- ;destroys it if file found)
- INT 21H ;call DOS
- POP [SI-2] ;restore drive letter
- POP CX ;restore loop count
- JNC FOUND_FILE ;if carry not set, then search
- ;was successful - jump.
- INC BYTE PTR [SI-2] ;increment drive letter char
- LOOP FIND_FILE ;and look on next drive
- ;
- ; did not find file. Return NOT_FOUND_CODE in errorlevel
- ;
- NO_FILE_EXIT: MOV AL,NOT_FOUND_CODE ;file not found on any drive
- EXIT: MOV AH,4CH ;DOS fn call to exit w/ errlev
- INT 21H ;call DOS and exit
- ;
- ; found the file. Retrieve the drive letter used in this last call,
- ; map it to disk number (A = 0, B = 1, etc) and return it in errorlevel.
- ;
- FOUND_FILE: MOV AL,[SI-2] ;get the drive letter (upper
- ;case ascii code)
- SUB AL,'A' ;map it to 0,1,2,3
- ;
- ; Set the default drive designator to the drive on which the file
- ; was found
- ;
- PUSH AX ;save AL
- MOV DL,AL ;drive number (0,1,2,...)
- MOV AH,0EH ;DOS fn "select disk"
- INT 21H ;call DOS and set default
- POP AX ;restore AL
- JMP EXIT ;and return it in errorlevel
- START ENDP
- page
- ;
- ; CRIT_HAND Critical Error Handler
- ;
- ; This handler will be called by DOS functions when any critical
- ; error (disk or non-disk) occurs during DOS INT 21H calls that
- ; are made during execution of this process.
- ;
- ; We only want to ignore disk errors, so we first test if the disk
- ; is the cause of error.
- ;
- ; If not a disk error, we jump to the parent's critical error handler
- ; (we JMP so that stack looks as if we were never there).
- ;
- ; If it is a disk error, we return an IGNORE code to the calling
- ; DOS function. The effect of all this is that when a DOS function
- ; tries to access a disk drive that has a door open, or no disk, or
- ; disk is unformatted, or disk is garbled, etc, the DOS function will
- ; simply give up and return to the function's caller "empty handed".
- ; There will be no "abort, retry, ignore" message from the critical
- ; error handler.
- ;
- ; on entry: Bit 7 of AH = 0 if disk error
- ; = 1 if not a disk error
- ;
- ; on exit: If disk error, we set AL = 0, "ignore error"
- ;
- ; registers affected: AH, AL
- ;
- CRIT_HAND PROC FAR ;RETS are typed FAR
- TEST AH,80H ;bit 7 set?
- JNZ NOT_DISK ;jump if yes,not disk error,
- ;don't treat it
- ;
- ; Treatment of disk errors is easy, just tell system to ignore them
- ;
- SUB AL,AL ;zero AL, "ignore" code
- IRET ;caller used INT so we IRET
- ;
- ; It was not a disk error, so let the "parent" critical error handler
- ; treat it by JMPing to its address that we saved.
- ;
- ; We JMP so we dont disturb the stack. Stack looks like we were
- ; never called.
- ;
- NOT_DISK: JMP DWORD PTR PARENT_HAND ;jump to parent crit err hand
- ;
- CRIT_HAND ENDP
- ;
- ;
- ; temporary storage of parent's critical handler address
- ;
- PARENT_HAND DD 1 DUP(?) ;double word for FAR address
- ;
- ;
- ;
- ; error message string
- ;
- ERROR_MESSAGE DB CR,LF,'***** No filename was given with '
- DB 'SETDISK *****',CR,LF,'$'
- ;
- ;
- COM_CODE ENDS
- END START
- Ä├╣ QÜ└éÄ^■ïσ]╦MW_F